package com.by.course.serivce.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by.course.config.web.jwt.JwtService;
import com.by.course.entity.base.BaseResult;
import com.by.course.entity.base.PageResult;
import com.by.course.entity.bo.BaseCourse;
import com.by.course.entity.bo.BaseUser;
import com.by.course.entity.bo.BaseUserBind;
import com.by.course.entity.vo.course.resp.BaseCourseResultVO;
import com.by.course.entity.vo.login.req.LoginVO;
import com.by.course.entity.vo.login.resp.LoginResultVO;
import com.by.course.entity.vo.user.req.AddBaseUserVO;
import com.by.course.entity.vo.user.req.DeleteBaseUserVO;
import com.by.course.entity.vo.user.req.GetBaseUserVO;
import com.by.course.entity.vo.user.req.UpdateBaseUserVO;
import com.by.course.entity.vo.user.resp.BaseUserResultVO;
import com.by.course.enums.CommonStatusEnum;
import com.by.course.enums.ErrEnum;
import com.by.course.enums.UserRoleEnum;
import com.by.course.execption.BusinessException;
import com.by.course.mapper.BaseStudentCourseMapper;
import com.by.course.mapper.BaseUserBindMapper;
import com.by.course.mapper.BaseUserMapper;
import com.by.course.serivce.BaseCourseService;
import com.by.course.serivce.BaseStudentCourseService;
import com.by.course.serivce.BaseUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.by.course.entity.base.PageResult.genEmptyData;

@Slf4j
@Service
public class BaseUserServiceImpl extends ServiceImpl<BaseUserMapper, BaseUser> implements BaseUserService {

    @Resource
    private BaseUserMapper baseUserMapper;

    @Resource
    private BaseUserService baseUserService;

    @Resource
    private BaseUserBindMapper baseUserBindMapper;

    @Resource
    private JwtService jwtService;

    @Resource
    private BaseStudentCourseMapper baseStudentCourseMapper;

    @Resource
    private BaseStudentCourseService baseStudentCourseService;

    @Resource
    private BaseCourseService baseCourseService;

    @Override
    public BaseResult<LoginResultVO> login(LoginVO vo) {
        BaseUser baseUser = baseUserMapper.login(vo.getMobilePhone(), vo.getPassword());
        if (baseUser == null) {
            throw new BusinessException("用户名或密码错误", ErrEnum.USER_ERR.getCode());
        }
        String jwt = jwtService.getJwt(baseUser.getId(), RandomUtil.randomString(5));
        LoginResultVO loginRespVO = new LoginResultVO();
        loginRespVO.setToken(jwt);
        loginRespVO.setUserId(baseUser.getId());
        loginRespVO.setRoleId(baseUser.getRole());
        return new BaseResult.Builder<LoginResultVO>().setData(loginRespVO).build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<String> createUser(AddBaseUserVO vo) {
        if (vo.getParentUserId() == null) {
            throw new BusinessException("用户名或密码错误", ErrEnum.USER_ERR.getCode());
        }
        BaseUser parentUser = baseUserMapper.selectByPrimaryKey(vo.getParentUserId());
        if (parentUser == null || !Objects.equals(parentUser.getRole(), UserRoleEnum.TEACHER.getCode())) {
            throw new BusinessException("用户名或密码错误", ErrEnum.USER_ERR.getCode());
        }

        BaseUser baseUser = baseUserMapper.selectUserByMobilePhone(vo.getMobilePhone());
        if (baseUser == null) {
            baseUser = new BaseUser();
            BeanUtil.copyProperties(vo, baseUser);
            baseUserMapper.insertSelective(baseUser);
        }

        BaseUserBind userBind = new BaseUserBind();
        userBind.setStudentId(baseUser.getId());
        userBind.setTeacherId(vo.getParentUserId());
        userBind.setPeriod(vo.getPeriod());
        baseUserBindMapper.insertSelective(userBind);

        List<Long> courseIdList = vo.getCourseIdList();
        if (CollectionUtil.isNotEmpty(courseIdList)) {
            baseStudentCourseService.saveBatchByCourseIdList(vo.getCourseIdList(), baseUser.getId());
        }

        return BaseResult.builder().build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<String> updateUser(UpdateBaseUserVO vo) {
        if (vo.getId() == null) {
            throw new BusinessException("请求的用户ID为空", ErrEnum.USER_ERR.getCode());
        }
        BaseUser baseUser = baseUserMapper.selectByPrimaryKey(vo.getId());
        if (baseUser == null) {
            throw new BusinessException("用户不存在", ErrEnum.USER_ERR.getCode());
        }
        if (vo.getStatus() != null) {
            baseUser.setStatus(vo.getStatus());
        }
        if (StringUtils.isNotBlank(vo.getMobilePhone())) {
            baseUser.setMobilePhone(vo.getMobilePhone());
        }
        if (StringUtils.isNotBlank(vo.getPassword())) {
            baseUser.setPassword(vo.getPassword());
        }
        if (vo.getRole() != null) {
            baseUser.setRole(vo.getRole());
        }
        if (StringUtils.isNotBlank(vo.getHeadImg())) {
            baseUser.setHeadImg(vo.getHeadImg());
        }
        if (StringUtils.isNotBlank(vo.getNickName())) {
            baseUser.setNickName(vo.getNickName());
        }
        if (vo.getGender() != null) {
            baseUser.setGender(vo.getGender());
        }
        if (vo.getBirthDay() != null) {
            baseUser.setBirthDay(vo.getBirthDay());
        }
        if (StringUtils.isNotBlank(vo.getProvince())) {
            baseUser.setProvince(vo.getProvince());
        }
        if (StringUtils.isNotBlank(vo.getCity())) {
            baseUser.setCity(vo.getCity());
        }
        if (StringUtils.isNotBlank(vo.getCountry())) {
            baseUser.setCountry(vo.getCountry());
        }
        baseUserMapper.updateByPrimaryKey(baseUser);

        List<Long> courseIdList = vo.getCourseIdList();
        if (CollectionUtil.isNotEmpty(courseIdList)) {
            baseStudentCourseMapper.deleteByCourseIdList(vo.getId(), vo.getCourseIdList());
            baseStudentCourseService.saveBatchByCourseIdList(vo.getCourseIdList(), baseUser.getId());
        }

        return BaseResult.builder().build();
    }

    @Override
    public BaseResult<String> deleteUser(DeleteBaseUserVO vo) {
        if (vo.getId() == null) {
            throw new BusinessException("删除用户失败", ErrEnum.USER_ERR.getCode());
        }
        BaseUser baseUser = new BaseUser();
        baseUser.setId(vo.getId());
        baseUser.setStatus(CommonStatusEnum.CLOSE.getCode());
        int count = baseUserMapper.updateByPrimaryKey(baseUser);
        if (count == 0) {
            throw new BusinessException("删除用户失败", ErrEnum.USER_ERR.getCode());
        }
        return BaseResult.builder().build();
    }

    @Override
    public BaseResult<BaseUserResultVO> getUserById(GetBaseUserVO vo) {
        BaseUser baseUser = baseUserMapper.selectByPrimaryKey(vo.getId());
        BaseUserResultVO baseUserResultVO = new BaseUserResultVO();
        BeanUtil.copyProperties(baseUser, baseUserResultVO);

//        List<Long> courseIdList = baseStudentCourseMapper.selectCourseListByUserId(vo.getId());
//        List<BaseCourse> baseCourseList = baseCourseService.listByIds(courseIdList);
//        if (CollectionUtil.isNotEmpty(baseCourseList)) {
//            List<CourseInfo> courseInfoList = baseCourseList.stream().map(t -> {
//                CourseInfo courseInfo = new CourseInfo();
//                courseInfo.setId(t.getId());
//                courseInfo.setName(t.getName());
//                return courseInfo;
//            }).collect(Collectors.toList());
//            baseUserResultVO.setBaseCourseList(courseInfoList);
//        }

        if (baseUser.getRole().equals(UserRoleEnum.TEACHER.getCode())) {
            List<Long> userIdList = baseUserBindMapper.selectUserListByTeacherId(vo.getId());
            if (CollectionUtil.isNotEmpty(userIdList)) {
                List<BaseUser> baseUsers = baseUserMapper.selectBatchIds(userIdList);
                if (CollectionUtil.isNotEmpty(baseUsers)) {
                    baseUserResultVO.setUserList(baseUsers);
                }
            }
        }
        return new BaseResult.Builder<BaseUserResultVO>().setData(baseUserResultVO).build();
    }

    @Override
    public BaseResult<List<BaseCourseResultVO>> getUserCourseList(GetBaseUserVO vo) {
        List<Long> courseIdList = baseStudentCourseMapper.selectCourseListByUserId(vo.getId());
        List<BaseCourse> baseCourseList = baseCourseService.listByIds(courseIdList);
        List<BaseCourseResultVO> courseResultVoList = baseCourseList.stream().map(t -> {
            BaseCourseResultVO baseCourseResultVO = new BaseCourseResultVO();
            BeanUtil.copyProperties(t, baseCourseResultVO);
            return baseCourseResultVO;
        }).collect(Collectors.toList());
        return new BaseResult.Builder<List<BaseCourseResultVO>>().setData(courseResultVoList).build();
    }

    @Override
    public BaseResult<PageResult<BaseUserResultVO>> queryUsers(GetBaseUserVO vo) {
        if (vo.getPageSize() == null) {
            vo.setPageSize(10);
        }
        if (vo.getCurrentPage() == null) {
            vo.setCurrentPage(1);
        }
        vo.setOffset((vo.getCurrentPage() - 1) * vo.getPageSize());
        Integer count = baseUserMapper.countQueryUsers(vo);
        if (count == null || count == 0) {
            return new BaseResult.Builder<PageResult<BaseUserResultVO>>().setData(genEmptyData()).build();
        }
        List<BaseUserResultVO> baseUsers = baseUserMapper.queryUsers(vo);
        if (CollectionUtil.isNotEmpty(baseUsers)) {
            List<Long> teacherIdList = baseUsers.stream().map(BaseUserResultVO::getId).collect(Collectors.toList());
            List<BaseUserBind> baseUserBindList = baseUserBindMapper.selectBindByTeacherIdList(teacherIdList);
            Map<Long, List<Long>> map = baseUserBindList.stream().collect(Collectors.groupingBy(BaseUserBind::getTeacherId, Collectors.mapping(BaseUserBind::getStudentId, Collectors.toList())));
            baseUsers.forEach(t -> {
                List<Long> userIdList = map.get(t.getId());
                if (CollectionUtil.isNotEmpty(userIdList)) {
                    List<BaseUser> baseUsers1 = baseUserMapper.selectBatchIds(userIdList);
                    t.setUserList(baseUsers1);
                }
            });
        }
        PageResult<BaseUserResultVO> resultPage = new PageResult<>(baseUsers, count, vo.getCurrentPage(), vo.getPageSize());
        return new BaseResult.Builder<PageResult<BaseUserResultVO>>().setData(resultPage).build();
    }
}
